home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / DESKTOP / MYMENU.ZIP / Sources / SourceScan (.txt) < prev   
RISC OS BBC BASIC V Source  |  1996-12-10  |  43KB  |  1,439 lines

  1.  Richard Atterer 1996
  2. =0:sp=13:lr=14:
  3. $" at line ";
  4. /save$=":4.$.Coding.MyMenu.!MyMenu.ScanUtil"
  5. type$="Utility"
  6. ,size%=7<<10:
  7.  code% size%:L%=code%+size%
  8. debugging%=0
  9. debugging%
  10. "Lib:Debug2"
  11. *washerefile$="<MyMenu$Dir>.^.IWasHere"
  12. washerefile$="RAM:IWasHere"
  13.  private error numbers
  14. Err_UnknownCommand=1
  15. Err_WrongSpecial=2
  16. Err_SpecExists=3
  17. Err_SpecNotDef=4
  18. Err_OutOfSpace=5
  19. Err_ModUk=6
  20. Err_ModB=7
  21. Err_ModK=8
  22. Err_ModL=9
  23. Err_ModM=10
  24. Err_MOnceOnly=11
  25. Err_NoCLI=12
  26. Err_EmptyMenu=13
  27. Err_NoKeys=14
  28. Err_WrongCommPos=15
  29. Err_DoubleKey=16
  30. !code%=3:
  31. "OS_Word",14,code%:
  32. "Territory_ConvertDateAndTime",1,code%,code%+8,256,"%DY %M3 %CE%YR"
  33. ,A%:d$="":
  34. B%=code%+8 
  35. A%-1:d$=d$+
  36. p%=12
  37. 2:O%=code%:P%=0
  38. :p=p%:
  39. B%,B%,C%:
  40. p%=14 
  41. C%>0 p=p%
  42. $    [optp
  43. %-;________________________________________
  44. ;format of "menu" RMA block
  45. ;--------------------------
  46. ;for each menu:
  47. *@;  4  width of menu items (when displaying with system font)
  48. + ;  4  number of menu items=N
  49. ;16*N items
  50. ;for each item:
  51. .=;  4  number of submenu (invisible main menu has nr 0) or
  52. /*;     (offset of *commands)
  53.  1<<31, or
  54. 0+;     (file offset of *commands)
  55.  1<<30
  56. 16;     bit 28 set indicates icon data is indirected
  57. ; 12  menu icon data
  58. 3D;     if not indirected; 12 text, up to 12 chars, padded with 0s
  59. 4C;     if indirected;      4 offset of text in "indir" RMA block
  60. 5L;                         4 -1 (or offset of "Sxxxxx" validation string)
  61. 6J;                         4 length of text incl. terminator (a 0 byte)
  62. 7P;"indir" RMA block contains a number of strings, either indirected item text
  63. ;or buffered *commands
  64. :6;format of hotkeys (stored downwards from R12+896)
  65. ;-----------------
  66. <D;   4  key(s) with 1st key in bits 24-31, 2nd in bits 16-23 etc.
  67. =0;   4  bits 0-1 = nr of keys in 1st word - 1
  68. >-;      bits 2-17 = nr of item inside menu
  69. ?";      bits 18-30 = nr of menu
  70. @K;      bit 31 set to make sure value is non-zero (needed by the module)
  71. AK;      (the word stored in "mouse" is the same format as this 2nd word)
  72. CJ;Note - this whole utility doesn't contain very optimized code because
  73. ;that's not necessary...
  74. E-;______...____________________;__________
  75. .utilstart
  76. bic    lr,lr,#1<<28
  77. stmfd  sp !,{lr}
  78. debugging%
  79.   [optp
  80.   bl IWasHere_NewFile
  81.   adr r0,utilstart
  82. d("address of executable=^0^"):]
  83. :[optp
  84. mov    r0,#0
  85. mov    r1,#var_end-4
  86. .clearvars
  87. str    r0,[r12,r1]
  88. subs   r1,r1,#4
  89. bpl    clearvars
  90. mvn    r0,#0
  91. str    r0,[r12,#sourceh]
  92. str    r0,[r12,#desth]
  93. add    r0,r12,#896
  94. str    r0,[r12,#hotkey]
  95. ;open source
  96. mov    r0,#&4F
  97. adr    r1,menufile
  98. swi    "XOS_Find"
  99. bvs    error
  100. str    r0,[r12,#sourceh]
  101. ;open destination
  102. ;mov    r0,#&8F
  103. ;adr    r1,scanfile
  104. ;swi    "XOS_Find"
  105. ;bvs    error
  106. ;str    r0,[r12,#desth]
  107. nB;claim extra workspace (initially 4k each, but may grow later)
  108. mov    r0,#6
  109. mov    r3,#4<<10
  110. swi    "XOS_Module"
  111. bvs    error
  112. str    r2,[r12,#menu]
  113. str    r3,[r12,#menusize]
  114. mov    r1,#0
  115. str    r1,[r2]
  116. str    r1,[r2,#4]
  117. mov    r1,#8
  118. str    r1,[r12,#menuused]
  119. mov    r3,#4<<10
  120. swi    "XOS_Module"
  121. bvs    error
  122. str    r2,[r12,#indir]
  123. str    r3,[r12,#indirsize]
  124. ;____________
  125. ,.scanloop                     ;MAIN LOOP
  126. bl     getstring
  127. bvs    endloop
  128. M;ldr    r2,[r12,#stringstart]  ;strip any leading spaces/tabs from string
  129. ;sub    r2,r2,#1
  130. ;.scanloop1
  131. ;ldrb   r0,[r2,#1]!
  132. ;teq    r0,#9
  133. ;teqne  r0,#32
  134. ;beq    scanloop1
  135. !;str    r2,[r12,#stringstart]
  136. ;____________
  137. .scanloop2
  138. ;adr    r1,specialstr          ;special char definition?
  139. bl     stringstarteq
  140. teq    r0,#0
  141. 'bne    scanloop3              ;nope
  142. ldrb   r0,[r12,#special]
  143. ;teq    r0,#0                  ;special already defined?
  144. movne  r3,#Err_SpecExists
  145. ,bne    report                 ;y > error
  146.  ldr    r2,[r12,#stringstart]
  147. ldr    r3,[r12,#stringend]
  148. sub    r1,r3,r2
  149. Oteq    r1,#9                  ;is there just one char after the "Special" ?
  150. -movne  r3,#Err_WrongSpecial   ;no > error
  151. bne    report
  152. ?ldrb   r0,[r2,#8]             ;r0=
  153. II value of special char
  154. strb   r0,[r12,#special]
  155. b      scanloop
  156. +.menufile     dcb"<MyMenu$M>.Menu":dcb0
  157. $.specialstr   dcb"Special:":dcb0
  158. +.bufferallstr dcb"BufferAll":dcb10:dcb0
  159. 4.ondemandstr  dcb"LoadOnDemand":dcb10:dcb0:align
  160. -;________________________________________
  161. .scanloop3
  162. Ladr    r1,bufferallstr        ;buffer all *commands (ignore B modifier)?
  163. bl     stringstarteq
  164. teq    r0,#0
  165. 'bne    scanloop4              ;nope
  166. d("BufferAll")
  167. ldr    r0,[r12,#menuused]
  168. teq    r0,#8
  169. mov    r3,#Err_WrongCommPos
  170. bne    report
  171. 3strb   r3,[r12,#bufferallinit] ;is non-zero now
  172. b      scanloop
  173. -;________________________________________
  174. .scanloop4
  175. Qadr    r1,ondemandstr        ;load MenuScan file only when hotkey is pressed?
  176. bl     stringstarteq
  177. teq    r0,#0
  178. 'bne    scanloop5              ;nope
  179. ldr    r0,[r12,#menuused]
  180. d("LoadOnDemand")
  181. teq    r0,#8
  182. mov    r3,#Err_WrongCommPos
  183. bne    report
  184. mvn    r0,#0
  185. /strb   r3,[r12,#ondemand]     ;non-zero now
  186. #;strb   r3,[r12,#bufferallinit]
  187. b      scanloop
  188. -;________________________________________
  189. ;r9=indir
  190. ;r10=current string ptr
  191. ;r11=special
  192. .scanloop5
  193. ldrb   r11,[r12,#special]
  194. ;teq    r11,#0                 ;special already defined?
  195. moveq  r3,#Err_SpecNotDef
  196. beq    report
  197. ldr    r9,[r12,#indir]
  198. !ldr    r10,[r12,#stringstart]
  199. ldrb   r0,[r10],#1
  200. 'teq    r0,r11                 ;"*"?
  201. bne    syntaxerror
  202. ldrb   r0,[r10],#1
  203. (teq    r0,r11                 ;"**"?
  204. bne    entry
  205. ;____________
  206. Q;search for the specified "menu path" - if any menus don't exist, create them
  207. E;r0=current menu, r1=current item, r2=items left in current menu,
  208. 5;r3=submenu levels left (during search for menus)
  209. .menucommand
  210. d("menucommand")
  211. mov    r0,r10
  212. Pmov    r3,#0                  ;r3=nr of "*"s in this line after initial "**"
  213. .menu1
  214. ldrb   r1,[r0],#1
  215. teq    r1,r11
  216. addeq  r3,r3,#1
  217. teq    r1,#10
  218. bne    menu1
  219. teq    r3,#0
  220. beq    syntaxerror
  221. ldr    r0,[r12,#menu]
  222. 9.menu2                        ;r0=ptr to current menu
  223. add    r1,r0,#8
  224. ldmib  r0,{r2}
  225. H.menu3                        ;r1=ptr to current item, r2=items left
  226. subs   r2,r2,#1
  227. >bmi    menu_create            ;not found > create new menu
  228. ldmia  r1!,{r4-r7}
  229. <tst    r4,#3<<30              ;is this a submenu number?
  230. 0bne    menu3                  ;n > next item
  231. mov    r8,r10
  232. 6tst    r4,#1<<28              ;is data indirected?
  233. Faddne  r5,r9,r5               ;y > calc string address from offset
  234. $subeq  r5,r1,#12              ;n
  235. Gmoveq  r7,#13                 ;n (length incl IMAGINARY terminator)
  236. Q;at this point for both indirected and not, r5=ptr to string, r7=max length+1
  237. I.menu4                        ;compare submenu's name with our string
  238. ldrb   r14,[r8],#1
  239. teq    r14,r11
  240. =moveq  r14,#0                 ;special char is terminator
  241. subs   r7,r7,#1
  242. ldrneb r6,[r5],#1
  243. Nmoveq  r6,#0                  ;important for non-indir. icons of length 12
  244. teq    r14,r6
  245. >bne    menu3                  ;not same string > next item
  246. ,teq    r14,#0                 ;finished?
  247. bne    menu4
  248. /;found submenu item with our string as name
  249. d("menu^^submenu with name found")
  250. bic    r4,r4,#3<<28
  251. 4subs   r3,r3,#1               ;further submenus?
  252. !streq  r1,[r12,#leafmenuitem]
  253. streq  r4,[r12,#entrymenu]
  254. $beq    menu_modifiers         ;n
  255. ?.menu5                        ;NB r4 is still nr of submenu
  256. ldr    r0,[r12,#menu]
  257. .menu6
  258. Kldmia  r0!,{r1-r2}            ;load of r1 not necessary, but never mind
  259. 9add    r0,r0,r2,lsl#4         ;16 bytes for each item
  260. subs   r4,r4,#1
  261. bne    menu6
  262. Imov    r10,r8                 ;r10 now ptr to string for next submenu
  263. b      menu2
  264. ;____________
  265. O;one of the menus specified didn't exist, so now create it and also further
  266. ;submenus inside it, if any
  267. .menu_create
  268. d("menu^^create new submenu - current menu=^0^")
  269. !Lldr    r1,[r12,#nrofmenus]    ;first append submenu item to current menu
  270. add    r1,r1,#1
  271. str    r1,[r12,#nrofmenus]
  272. str    r1,[r12,#entrymenu]
  273. sub    r8,r10,#1
  274. .menu_create1
  275. ldrb   r2,[r8,#1]!
  276. teq    r2,r11
  277. bne    menu_create1
  278. bl     insertnewitem
  279. ,=ldmia  r0!,{r2,r4}            ;r2 not needed - never mind
  280. add    r2,r0,r4,lsl#4
  281. .Nstr    r2,[r12,#leafmenuitem] ;no need for offset - no mem claims from now
  282. 0P;create the new menu - NB 8 bytes space have been allocated by insertnewitem
  283. ldr    r0,[r12,#menu]
  284. mov    r2,#0
  285. ldr    r4,[r12,#menuused]
  286. add    r0,r0,r4
  287. 5Msub    r1,r1,#16              ;=min item width for a title of this length
  288. stmia  r0,{r1-r2}
  289. add    r4,r4,#8
  290. str    r4,[r12,#menuused]
  291. add    r10,r8,#1
  292. ;1subs   r3,r3,#1               ;more submenus?
  293. <Qbne    menu_create            ;y > don't search because current menu is empty
  294. =Padd    r8,r8,#1               ;    instead, create any further submenus imm.
  295. ;____________
  296. @+;r8=ptr to tail of line, with modifiers
  297. AP.menu_modifiers               ;interpretation of eg B;Kxx;L at end of string
  298. B"ldrb   r0,[r12,#bufferallinit]
  299. strb   r0,[r12,#bufferall]
  300. .menu_mod
  301. teq    r0,#10
  302. beq    scanloop
  303. .menu_mod1
  304. ldrb   r0,[r8],#1
  305. teq    r0,#10
  306. beq    scanloop
  307. N+teq    r0,#
  308. "b"             ;B modifier
  309. teqne  r0,#
  310. bne    menu_mod2
  311. d("menu^^B modifier")
  312. ldrb   r0,[r8],#1
  313. teq    r0,#
  314. teqne  r0,#10
  315. movne  r3,#Err_ModB
  316. bne    report
  317. W0strb   r0,[r12,#bufferall]    ;just non-zero
  318. b      menu_mod
  319. Z-.menu_mod2                    ;L modifier
  320. teq    r0,#
  321. teqne  r0,#
  322. bne    menu_mod3
  323. d("menu^^L modifier")
  324. ldrb   r0,[r8],#1
  325. teq    r0,#
  326. teqne  r0,#10
  327. movne  r3,#Err_ModL
  328. bne    report
  329. d!ldr    r1,[r12,#leafmenuitem]
  330. ldr    r2,[r1,#-16]
  331. orr    r2,r2,#1<<29
  332. str    r2,[r1,#-16]
  333. b      menu_mod
  334. j-.menu_mod3                    ;M modifier
  335. teq    r0,#
  336. teqne  r0,#
  337. bne    menu_mod5
  338. ldrb   r0,[r8],#1
  339. d("menu^^M modifier")
  340. teq    r0,#
  341. teqne  r0,#10
  342. movne  r3,#Err_ModM
  343. bne    report
  344. ldr    r3,[r12,#mouse]
  345. teq    r3,#0
  346. movne  r3,#Err_MOnceOnly
  347. bne    report
  348. ldr    r1,[r12,#menu]
  349. z!ldr    r7,[r12,#leafmenuitem]
  350. mov    r4,#0
  351. |B.menu_mod4                    ;search for "leafmenuitem"s menu
  352. ldmia  r1!,{r5-r6}
  353. add    r1,r1,r6,lsl#4
  354. cmp    r1,r7
  355. addlo  r4,r4,#1
  356. blo    menu_mod4
  357. sub    r1,r1,r6,lsl#4
  358. mov    r3,r4,lsl#18
  359. sub    r4,r7,r1
  360. sub    r4,r4,#16
  361. orr    r3,r3,r4,lsr#4-2
  362. -orr    r3,r3,#1<<31           ;set bit 31
  363. str    r3,[r12,#mouse]
  364. b      menu_mod
  365. -.menu_mod5                    ;K modifier
  366. teq    r0,#
  367. teqne  r0,#
  368. movne  r3,#Err_ModUk
  369. bne    report
  370. d("menu^^K modifier")
  371. mov    r0,#16
  372. mov    r1,r8
  373. swi    "XOS_ReadUnsigned"
  374. movvs  r3,#Err_ModK
  375. bvs    report
  376. sub    r3,r1,r8
  377. movs   r3,r3,lsr#1
  378. movcs  r3,#Err_ModK
  379. =bcs    report                 ;need even number of digits
  380. sub    r3,r3,#1
  381. ldr    r0,[r12,#menu]
  382. !ldr    r7,[r12,#leafmenuitem]
  383. mov    r4,#0
  384. B.menu_mod6                    ;search for "leafmenuitem"s menu
  385. ldmia  r0!,{r5-r6}
  386. add    r0,r0,r6,lsl#4
  387. cmp    r0,r7
  388. addlo  r4,r4,#1
  389. blo    menu_mod6
  390. sub    r0,r0,r6,lsl#4
  391. orr    r3,r3,r4,lsl#18
  392. sub    r4,r7,r0
  393. sub    r4,r4,#16
  394. orr    r3,r3,r4,lsr#4-2
  395. bl     hotkeyentry
  396. mov    r8,r1
  397. ldrb   r0,[r8],#1
  398. teq    r0,#
  399. teqne  r0,#10
  400. movne  r3,#Err_ModK
  401. bne    report
  402. b      menu_mod
  403. -;________________________________________
  404. .entry
  405. sub    r10,r10,#1
  406. >ldr    r5,[r12,#menu]         ;find menu to place entry in
  407. ldr    r4,[r12,#entrymenu]
  408. d("entry^^entrymenu=^4^")
  409. mov    r0,r4
  410. .entry1
  411. subs   r0,r0,#1
  412. ldmgeiar5!,{r2-r3}
  413. addge  r5,r5,r3,lsl#4
  414. bge    entry1
  415. 3ldr    r8,[r12,#stringend]    ;find end of line
  416. .entry2
  417. ldrb   r0,[r8,#-1]!
  418. teq    r0,r11
  419. bne    entry2
  420. ldrb   r6,[r12,#bufferall]
  421. teq    r6,#0
  422. moveq  r6,#1<<31
  423. movne  r6,#1<<30
  424. add    r7,r8,#1
  425. mov    r1,#0
  426. ;______
  427. .entry_mod
  428. teq    r1,#10
  429. beq    entry3
  430. .entry_mod1
  431. ldrb   r1,[r7],#1
  432. teq    r1,#10
  433. beq    entry3
  434. +teq    r1,#
  435. "b"             ;B modifier
  436. teqne  r1,#
  437. bne    entry_mod2
  438. d("entry^^B modifier")
  439. ldrb   r1,[r7],#1
  440. teq    r1,#
  441. teqne  r1,#10
  442. movne  r3,#Err_ModB
  443. bne    report
  444. bic    r6,r6,#1<<31
  445. orr    r6,r6,#1<<30
  446. b      entry_mod
  447. -.entry_mod2                   ;L modifier
  448. teq    r1,#
  449. teqne  r1,#
  450. bne    entry_mod3
  451. d("entry^^L modifier")
  452. ldrb   r1,[r7],#1
  453. teq    r1,#
  454. teqne  r1,#10
  455. movne  r3,#Err_ModL
  456. bne    report
  457. orr    r6,r6,#1<<29
  458. b      entry_mod
  459. -.entry_mod3                   ;M modifier
  460. teq    r1,#
  461. teqne  r1,#
  462. bne    entry_mod4
  463. d("entry^^M modifier")
  464. ldrb   r1,[r7],#1
  465. teq    r1,#
  466. teqne  r1,#10
  467. movne  r3,#Err_ModM
  468. bne    report
  469. ldr    r3,[r12,#mouse]
  470. teq    r3,#0
  471. movne  r3,#Err_MOnceOnly
  472. bne    report
  473. mov    r3,r4,lsl#18
  474. ldmib  r5,{r0}
  475. orr    r3,r3,r0,lsl#2
  476. -orr    r3,r3,#1<<31           ;set bit 31
  477. str    r3,[r12,#mouse]
  478. b      entry_mod
  479.     -.entry_mod4                   ;K modifier
  480. teq    r1,#
  481. teqne  r1,#
  482. movne  r3,#Err_ModUk
  483. bne    report
  484. d("menu^^K modifier")
  485. mov    r0,#16
  486. mov    r1,r7
  487. swi    "XOS_ReadUnsigned"
  488. movvs  r3,#Err_ModK
  489. bvs    report
  490. sub    r3,r1,r7
  491. movs   r3,r3,lsr#1
  492. movcs  r3,#Err_ModK
  493. =bcs    report                 ;need even number of digits
  494. sub    r3,r3,#1
  495. orr    r3,r3,r4,lsl#18
  496. ldmib  r5,{r0}
  497. orr    r3,r3,r0,lsl#2
  498. bl     hotkeyentry
  499. mov    r7,r1
  500. ldrb   r1,[r7],#1
  501. teq    r1,#
  502. teqne  r1,#10
  503. movne  r3,#Err_ModK
  504. bne    report
  505. b      entry_mod
  506. ;______
  507. .entry3
  508. )Ftst    r6,#1<<31              ;*commands to be buffered in memory?
  509. beq    entry4
  510. +$mov    r0,#0                  ;n
  511. ldr    r1,[r12,#sourceh]
  512. swi    "XOS_Args"
  513. bvs    error
  514. orr    r6,r6,r2
  515. .entry4
  516. mov    r0,r5
  517. mov    r1,r6
  518. bl     insertnewitem
  519. tst    r6,#1<<31
  520. bne    entry10
  521. ldmia  r0!,{r1-r2}
  522. add    r0,r0,r2,lsl#4
  523. ldr    r1,[r12,#indirused]
  524. ldr    r2,[r0,#-16]
  525. orr    r2,r2,r1
  526. str    r2,[r0,#-16]
  527. .entry10
  528. bl     getstring
  529. movvs  r3,#Err_NoCLI
  530. @ ldrvc  r1,[r12,#stringstart]
  531. bvs    report
  532. ldrb   r0,[r1],#-1
  533. teq    r0,r11
  534. moveq  r3,#Err_NoCLI
  535. beq    report
  536. tst    r6,#1<<31
  537. bne    entry8
  538. ;______
  539. d("*command to be buffered in memory")
  540. K@mov    r0,#13                 ;*comms 2 B buffered in memory
  541. add    r2,r12,#indir
  542. ldmia  r2,{r2,r8-r9}
  543. .entry5
  544. add    r10,r1,#1
  545. add    r5,r2,r9
  546. ldr    r7,[r12,#stringend]
  547. sub    r6,r7,r10
  548. SNsub    r4,r5,#8<<10           ;8k limit when searching for matching *comms
  549. cmp    r4,r2
  550. movlo  r4,r2
  551. bl     indirmatch
  552. subcs  r7,r7,r1
  553. bcs    entry12
  554. add    r4,r2,r9
  555. sub    r4,r4,r5
  556. d("entry5^^0=^0^, 1=^1^, 2=^2^, ^4^ bytes ago=^5^, 6=^6^, 10=^10^")
  557. d("entry^^match ^4^ bytes ago")
  558. ]Mstrb   r4,[r1,#2]             ;NB hi-lo and not lo-hi, to ensure that the
  559. ^;mov    r4,r4,lsr#8            ;first byte is always <32
  560. strb   r4,[r1,#1]
  561. mov    r4,#10
  562. strb   r4,[r1,#3]
  563. mov    r7,#3
  564. ;add r10,r2,#&ed0
  565. ;ldmib r10,{r3,r4}
  566. d("entry^^at &ed4 ^4^ ^3^")
  567. .entry12
  568. d("entry12^^*comm of length ^7^ at ^1^")
  569. add    r9,r9,r7
  570. jNsubs   r3,r9,r8               ;sets the flags in the same way as cmp r9,r8
  571. ble    entry6
  572. d("*2Bbuf before^^addr=^2^, size=^8^, new used=^9^, size needed=^7^")
  573. add    r3,r3,#&ff
  574. n+bic    r3,r3,#&ff             ;round up
  575. o3swi    "XOS_Module"           ;expand RMA block
  576. bvs    error
  577. add    r8,r8,r3
  578. d("*2Bbuf after^^addr=^2^, size=^8^, used=^9^")
  579. .entry6
  580. add    r4,r2,r9
  581. sub    r4,r4,r7
  582. .entry7
  583. ldrb   r3,[r1,#1]!
  584. strb   r3,[r4],#1
  585. subs   r7,r7,#1
  586. bne    entry7
  587. bl     getstring
  588. } ldrvc  r1,[r12,#stringstart]
  589. bvs    entry11
  590. ldrb   r14,[r1],#-1
  591. teq    r14,r11
  592. bne    entry5
  593. ;______
  594. mov    r0,#0
  595. <strb   r0,[r4,#-1]            ;to indicate last *command
  596. add    r0,r12,#indir
  597. stmia  r0,{r2,r8-r9}
  598. b      scanloop3
  599. ;____________
  600. :.entry8                       ;*comms not 2 B buffered
  601. d("*commands not to be buffered")
  602. ldr    r2,[r12,#osclilen]
  603. .entry9
  604. ldr    r6,[r12,#stringend]
  605. sub    r7,r6,r1
  606. cmp    r2,r7
  607. movlt  r2,r7
  608. bl     getstring
  609.  ldrvc  r1,[r12,#stringstart]
  610. str    r2,[r12,#osclilen]
  611. bvs    endloop
  612. ldrb   r14,[r1],#-1
  613. teq    r14,r11
  614. bne    entry9
  615. b      scanloop3
  616. -;________________________________________
  617. .hotkeyentry
  618. K;r2/r3=words to be placed in buffer for hotkeys (r3 bit 31 still unset)
  619. stmfd  sp !,{r4,lr}
  620. orr    r3,r3,#1<<31
  621. ldr    r0,[r12,#hotkey]
  622. stmdb  r0!,{r2-r3}
  623. str    r0,[r12,#hotkey]
  624. P;sort key numbers in hotkey def's from lowest in byte 0 to highest in byte 3
  625. mov    r2,r0
  626. add    r0,r0,#3
  627. P.hotkeyentry1                 ;Quicksort-like, though not particularly quick
  628. ldrb   r3,[r2],#1
  629. mov    r4,r2
  630. .hotkeyentry2
  631. ldrb   lr,[r4],#1
  632. cmp    r3,lr
  633. strgtb r3,[r4,#-1]
  634. movgt  r3,lr
  635. strgtb lr,[r2,#-1]
  636. cmp    r4,r0
  637. bls    hotkeyentry2
  638. cmp    r2,r0
  639. blo    hotkeyentry1
  640. I;check if this hotkey combination has already been used - error if so
  641. add    r2,r12,#896
  642. sub    r0,r0,#3
  643. ldr    r3,[r0],#8
  644. .hotkeyentry3
  645. teq    r0,r2
  646. ldmeqfdsp !,{r4,pc}^
  647. ldr    r4,[r0],#8
  648. teq    r3,r4
  649. bne    hotkeyentry3
  650. add sp,sp,#8
  651. mov    r3,#Err_DoubleKey
  652. b      report
  653. -;________________________________________
  654. .entry11
  655. mov    r0,#0
  656. <strb   r0,[r4,#-1]            ;to indicate last *command
  657. add    r0,r12,#indir
  658. stmia  r0,{r2,r8-r9}
  659. F;Yeee-Haaa! We've managed not to crash during interpretation, so -
  660.  ;  D O   I T   N O W . . . ?
  661. .endloop
  662. -; write the 'MenuScan' file in this form:
  663. +; 4  total size of RMA block needed, ie
  664. N;    size of hotkey definitions + size of Wimp style menus + size of indir
  665. (; 4  size of hotkeys (multiple of 8)
  666. .; 4  length of largest unbuffered *command
  667. /; 4  nr of menus (incl invisible main menu)
  668. H; 1  zero for keeping menu in memory, non-zero for loading on demand
  669. ; 1  special character
  670. ; 2  zero bytes to align
  671. ?; 4  menu & icon nr of "M" modifier item - zero if not used
  672. *; ?  hotkey definitions (8 bytes each)
  673. L; ?  menu in Wimp format, ie can be passed to Wimp_CreateWindow once all
  674. 2;    offsets have been replaced with addresses
  675. ; ?  indirected data
  676. J;NB all offsets in hotkey/menu data are relative to start of menu data
  677. J;replace all submenu numbers with offsets from start of menu structure
  678. =;assumes a menu header needs 32 bytes, each item needs 28
  679. d("endloop^^will replace submenu items")
  680. .;  >>> WARNING! SPAGHETTI CODE FOLLOWS <<<
  681. ldr    r9,[r12,#hotkey]
  682. sub    r1,r9,r12
  683. rsbs   r8,r1,#896
  684. ldreq  r7,[r12,#mouse]
  685. teqeq  r7,#0
  686. moveq  r3,#Err_NoKeys
  687. beq    report
  688. Jadd    r7,r12,#string         ;will store addresses of menu items here
  689. ldr    r11,[r12,#menu]
  690. mov    r0,r11
  691. ldr    r1,[r12,#nrofmenus]
  692. 0.endloop1                     ;for each menu
  693. ldmia  r0!,{r2-r3}
  694. 7teq    r3,#0                  ;if no entries, error
  695. moveq  r3,#Err_EmptyMenu
  696. beq    report
  697. 0.endloop2                     ;for each item
  698. ldr    r2,[r0],#16
  699. :tst    r2,#3<<30              ;is item a submenu item?
  700. Ableq   endloop_submenu        ;y > replace number with offset
  701. subs   r3,r3,#1
  702. bne    endloop2
  703. subs   r1,r1,#1
  704. bpl    endloop1
  705. ;______
  706. d("endloop^^will write to file")
  707. mov    r0,#&83
  708. adr    r1,scanfile
  709. 5swi    "OS_Find"              ;create output file
  710. bvs    error
  711. str    r0,[r12,#desth]
  712. ldr    r9,[r12,#nrofmenus]
  713. add    r9,r9,#1
  714. mov    r4,r9
  715. mov    r5,r9
  716. ldr    r2,[r12,#menuused]
  717. 5sub    r10,r2,r5,lsl#3        ;r10=nr of items*16
  718. rsb    r2,r10,r10,lsl#3
  719. 4mov    r2,r2,lsr#2            ;r2=nr of items*28
  720. 5add    r2,r2,r5,lsl#5         ;r2+=nr of menus*32
  721. mov    r10,r2
  722. add    r1,r2,r8
  723. ldr    r5,[r12,#indirused]
  724. add    r1,r1,r5
  725. mov    r2,r8
  726. ldr    r3,[r12,#osclilen]
  727. ldrb   r5,[r12,#ondemand]
  728. ldrb   r6,[r12,#special]
  729. orr    r5,r5,r6,lsl#8
  730. ldr    r6,[r12,#mouse]
  731. stmfd  sp,{r1-r6}
  732. 6mov    r1,r0                  ;write 6 word header
  733. mov    r0,#2
  734. sub    r2,sp,#6<<2
  735. mov    r3,#6<<2
  736. swi    "XOS_GBPB"
  737. bvs    error
  738. "<mov    r0,#2                  ;and write hotkeys to file
  739. ldr    r2,[r12,#hotkey]
  740. mov    r3,r8
  741. swi    "XOS_GBPB"
  742. bvs    error
  743. (J;now write the menu data in Wimp format - each menu is preceded by the
  744. ):;additional info we need to store along with the items
  745. *(;  4  A=number of items in this menu
  746. +P; 4*A one word for each item, containing the submenu offset or (file) offset
  747. ; 28  Wimp menu header
  748. ;24*A Wimp menu items
  749. .M;r10=constant added to offsets into indir (=size of wimp style menu data)
  750. mov    r0,r11
  751. 0Dadd    r4,r12,#string         ;r4=ptr to submenu items for menus
  752. adr    r2,maindummy+16
  753. stmia  r4,{r2}
  754. .endloop7
  755. ldmia  r0!,{r2-r3}
  756. 5>mov    r8,r3                  ;write info before wimp menu
  757. bl     putword
  758. mov    r1,r0
  759. mov    r5,r3
  760. .endloop8
  761. ldr    r8,[r1],#16
  762. ;Htst    r8,#1<<30              ;is this a *command offset into indir?
  763. <$addne  r8,r8,r10              ;y
  764. bl     putword
  765. subs   r5,r5,#1
  766. bne    endloop8
  767. ldmia  r4!,{r5}
  768. B2stmfd  sp !,{r0,r3-r4}        ;write wimp menu
  769. ldr    r1,wimpmenucol
  770. mov    r3,#44
  771. mov    r4,#0
  772. FGstmfd  sp !,{r1-r2,r3,r4}     ;colours, width, height, vertical gap
  773. ldr    r6,[r5,#-16]
  774. and    r6,r6,#1<<28
  775. movs   r6,r6,lsr#28-8
  776. ldmdb  r5,{r0-r2}
  777. K0addne  r0,r0,r10              ;if indirected
  778. L9stmfd  sp !,{r0-r2}           ;icon data of title bar
  779. mov    r0,#2
  780. ldr    r1,[r12,#desth]
  781. mov    r2,sp
  782. mov    r3,#28
  783. swi    "XOS_GBPB"
  784. bvs    error
  785. add    sp,sp,#28
  786. ldmfd  sp !,{r5,r7}
  787. V8.endloop10                    ;write wimp menu items
  788. ldmia  r5!,{r0-r2,r4}
  789. tst    r0,#1<<28
  790. Y2addne  r1,r1,r10              ;text indirected
  791. Z,stmfd  sp !,{r1-r2,r4}        ;icon data
  792. mov    r1,r6
  793. mov    r6,#0
  794. mov    r2,r0
  795. ldr    r4,wimpmenuicon
  796. tst    r2,#1<<28
  797. `2orrne  r4,r4,#1<<8            ;text indirected
  798. tst    r2,#1<<29
  799. b.orrne  r1,r1,#1<<1            ;dotted line
  800. c0tst    r2,#3<<30              ;submenu item?
  801. biceq  r2,r2,#3<<28
  802. e<mvnne  r2,#0                  ;n > submenu pointer is -1
  803. teq    r7,#1
  804. g,orreq  r1,r1,#1<<7            ;last item
  805. hLbiceq  r1,r1,#1<<1            ;last item never followed by a dotted line
  806. stmfd  sp !,{r1-r2,r4}
  807. mov    r0,#2
  808. ldr    r1,[r12,#desth]
  809. mov    r2,sp
  810. mov    r3,#24
  811. swi    "XOS_GBPB"
  812. bvs    error
  813. add    sp,sp,#24
  814. subs   r7,r7,#1
  815. bne    endloop10
  816. ldmfd  sp !,{r4}
  817. subs   r9,r9,#1
  818. movne  r0,r5
  819. bne    endloop7
  820. ;______
  821. ldr    r2,[r12,#indir]
  822. ldr    r3,[r12,#indirused]
  823. |.swi    "XOS_GBPB"             ;write indir
  824. bvs    error
  825. ;______
  826. mvn    r0,#0
  827. str    r0,[r12,#desth]
  828. mov    r0,#0
  829. -swi    "XOS_Find"             ;close file
  830. bvs    error
  831. mov    r0,#17
  832. adr    r1,menufile+1024+512
  833. sub    r1,r1,#1024+512
  834. swi    "XOS_File"
  835. bvs    error
  836. Band    r2,r2,#&ff             ;important - preserve date stamp
  837. Lldr    r1,fileorr             ;(MyMenu module uses this to make sure the
  838. Eorr    r2,r2,r1               ;MenuScan file is still up to date)
  839. mov    r0,#2
  840. adr    r1,scanfile
  841. swi    "XOS_File"
  842. bvs    error
  843. mov    r0,#3
  844. adr    r1,scanfile
  845. swi    "XOS_File"
  846. bvs    error
  847. bl     closedown
  848. ldmvcfdsp !,{pc}^
  849. ldmfd  sp !,{lr}
  850. orrs   pc,lr,#1<<28
  851. 5.scanfile     dcb"<MyMenu$M>.MenuScan":dcb0:align
  852. .fileorr      dcd &fffffd00
  853. (.maindummy    dcd0:dcb"InvisiblMain"
  854. %.wimpmenucol  dcb7:dcb2:dcb7:dcb0
  855. 4.wimpmenuicon dcd%000000110001 
  856. (7<<24) 
  857. (0<<28)
  858. ;____________
  859. J;r2=nr of submenu, r4-r7 can be corrupted, r10=add, r11=menu, r14=link
  860. .endloop_submenu
  861. ;mov r7,lr
  862. d("endloop_submenu^^nr of submenu=^2^")
  863. ;mov lr,r7
  864. and    r4,r2,#3<<28
  865. bic    r2,r2,#3<<28
  866. Nstr    r0,[r7,r2,lsl#2]       ;we'll use this later to find menus' parents
  867. mov    r5,r11
  868. .endloop_submenu1
  869. 2add    r4,r4,#32              ;for menu header
  870. ldmib  r5,{r6}
  871. add    r5,r5,#8
  872. add    r5,r5,r6,lsl#4
  873. rsb    r6,r6,r6,lsl#3
  874. ,add    r4,r4,r6,lsl#2         ;r4+=r6*28
  875. subs   r2,r2,#1
  876. bne    endloop_submenu1
  877. ldmib  r5,{r6}
  878. add    r4,r4,#4
  879. add    r4,r4,r6,lsl#2
  880. str    r4,[r0,#-16]
  881. movs   pc,lr
  882. ;____________
  883. ;r8=word to be written
  884. .putword
  885. stmfd  sp !,{r0-r4,r8,lr}
  886. mov    r0,#2
  887. ldr    r1,[r12,#desth]
  888. add    r2,sp,#5<<2
  889. mov    r3,#4
  890. swi    "XOS_GBPB"
  891. bvs    error
  892. ldmfd  sp !,{r0-r4,r8,pc}^
  893. -;  >>> EOS <<<   (end of spaghetti code!)
  894. -;________________________________________
  895. -;________________________________________
  896. %;r1=ptr to null terminated string
  897. F;returns 0 in r0 if string begins with string at r1 (r0=-1 if not)
  898. .stringstarteq
  899. stmfd  sp !,{r1-r3,lr}
  900.  ldr    r2,[r12,#stringstart]
  901. .stringstarteq1
  902. ldrb   r0,[r1],#1
  903. teq    r0,#0
  904. 7ldmeqfdsp !,{r1-r3,pc}^       ;strings are the same
  905. ldrb   r3,[r2],#1
  906. eor    r0,r0,r3
  907. 4bics   r0,r0,#1<<5            ;case insensitive!
  908. beq    stringstarteq1
  909. 1mvn    r0,#0                  ;strings differ
  910. ldmfd  sp !,{r1-r3,pc}^
  911. -;________________________________________
  912. #;ignore empty and comment lines
  913. ;V set on exit if eof
  914. .getstring
  915. bic    lr,lr,#1<<28
  916. stmdb  sp,{r0-r2,lr}
  917. ldr    r0,[r12,#sourceeof]
  918. teq    r0,#0
  919. orrnes pc,lr,#1<<28
  920. d("getstring")
  921. ldr    r1,[r12,#sourceh]
  922. ?.getstring1                   ;loop for comment/empty lines
  923.  ldr    r2,[r12,#currentline]
  924. add    r2,r2,#1
  925. =str    r2,[r12,#currentline]  ;for correct error messages
  926. swi    "XOS_BGet"
  927. bvs    error
  928. bcs    getstring_eof
  929. teq    r0,#10
  930. beq    getstring1
  931. teq    r0,#
  932. beq    getstring3
  933. add    r2,r12,#string-1
  934. strb   r0,[r2,#1]!
  935. ldr    r3,[r12,#hotkey]
  936. A.getstring2                   ;loop for reading in valid line
  937. swi    "XOS_BGet"
  938. bvs    error
  939. 8strcs  r12,[r12,#sourceeof]   ;must just be non-zero
  940. movcs  r0,#10
  941. strb   r0,[r2,#1]!
  942. cmp    r2,r3
  943. movhs  r3,#Err_OutOfSpace
  944. bhs    report
  945. teq    r0,#10
  946. bne    getstring2
  947. ;ldr    r0,[r12,#hotkey]
  948. ;cmp    r2,r0
  949. ;movhs  r3,#Err_OutOfSpace
  950. ;bhs    report
  951. str    r2,[r12,#stringend]
  952. add    r2,r12,#string
  953.      str    r2,[r12,#stringstart]
  954. ldmdb  sp,{r0-r2,pc}^
  955. ;____________
  956. .getstring_eof
  957. 8str    r12,[r12,#sourceeof]   ;must just be non-zero
  958. ldmdb  sp,{r0-r2,lr}
  959. orrs   pc,lr,#1<<28
  960. ;____________
  961. 9.getstring3                   ;loop for comment lines
  962. swi    "XOS_BGet"
  963. bvs    error
  964. bcs    getstring_eof
  965. teq    r0,#10
  966. bne    getstring3
  967. b      getstring1
  968. -;________________________________________
  969. ;;insert a new menu item after last item of current menu
  970. @;r0=ptr to current menu, r1=1st word of item (eg submenu nr)
  971. /;r10=ptr to text, r8=ptr to byte after text
  972. 3;on exit r0=ptr to current menu, maybe shifted,
  973.  F;        r1=width of menu item (System font - for pre-RISC OS 3.5)
  974. .insertnewitem
  975. stmfd  sp !,{r2-r6,lr}
  976. d("insertnewitem^^menu=^0^, eg submenu nr=^1^, [^10^;^8^[ text")
  977. add    r14,r12,#menu
  978. ldmia  r14,{r2,r4-r5}
  979. &N;ensure 8 bytes too much, so menu_create needn't worry about ensuring them
  980. add    r5,r5,#16+8
  981. (Nsubs   r3,r5,r4               ;sets the flags in the same way as cmp r5,r4
  982. )Msub    r5,r5,#8               ;we don't need those 8 bytes at the moment!
  983. ble    insertnewitem1
  984. +.sub    r6,r0,r2               ;make offset
  985. mov    r0,#13
  986. add    r3,r3,#&ff
  987. .+bic    r3,r3,#&ff             ;round up
  988. /3swi    "XOS_Module"           ;expand RMA block
  989. bvs    error
  990. add    r4,r4,r3
  991. 25add    r0,r6,r2               ;make address again
  992. .insertnewitem1
  993. stmia  r14,{r2,r4-r5}
  994. add    r5,r2,r5
  995. ldmib  r0,{r2}
  996. add    r2,r0,r2,lsl#4
  997. add    r2,r2,#8
  998. sub    r4,r5,#16
  999. ;N.insertnewitem2               ;copy everything after current menu up by 16
  1000. teq    r4,r2
  1001. ldmnedbr4!,{r3}
  1002. stmnedbr5!,{r3}
  1003. bne    insertnewitem2
  1004. sub    r6,r8,r10
  1005. B?cmp    r6,#12                 ;must new icon be indirected?
  1006. C$movle  r4,#0                  ;n
  1007. movle  r5,#0
  1008. movle  r6,#0
  1009. FOstmleiar2,{r1,r4-r6}          ;if indir, store offset/-1/length, else 0/0/0
  1010. GFaddle  r1,r2,#4               ;r1=destination addr for item string
  1011. ble    insertnewitem4
  1012. addgt  r3,r12,#indir
  1013. ldmgtiar3,{r3,r5,r7}
  1014. mov    r4,r3
  1015. add    r5,r3,r7
  1016. bl     indirmatch
  1017. subcc  r4,r5,r3
  1018. debugging%
  1019.   [optp
  1020.   bcs debug1
  1021. d("insertnewitem^^match at offset ^4^")
  1022.   .debug1:]
  1023. :[optp
  1024. V$add    r6,r6,#1               ;y
  1025. movcs  r4,r7
  1026. mvn    r5,#0
  1027. YCorr    r1,r1,#1<<28           ;set flag to indicate indirection
  1028. ZOstmia  r2,{r1,r4-r6}          ;if indir, store offset/-1/length, else 0/0/0
  1029. bcc    insertnewitem6
  1030. ]K;the newly created item has indirected text - ensure mem in indir block
  1031. d("insertnewitem^^indirected")
  1032. add    r14,r12,#indir
  1033. ldmia  r14,{r2,r4-r5}
  1034. mov    r1,r5
  1035. add    r5,r5,r6
  1036. subs   r3,r5,r4
  1037. ble    insertnewitem3
  1038. stmfd  sp !,{r0}
  1039. mov    r0,#13
  1040. add    r3,r3,#&ff
  1041. h+bic    r3,r3,#&ff             ;round up
  1042. i3swi    "XOS_Module"           ;expand RMA block
  1043. bvs    error
  1044. add    r4,r4,r3
  1045. ldmfd  sp !,{r0}
  1046. .insertnewitem3
  1047. stmia  r14,{r2,r4-r5}
  1048. oFadd    r1,r2,r1               ;r1=destination addr for item string
  1049. mov    r2,#0
  1050. sub    r6,r6,#1
  1051. r;strb   r2,[r1,r6]             ;already store terminator
  1052. tO;now copy the item's string - either to 12 byte icon data or to indir block
  1053. .insertnewitem4
  1054. mov    r6,r10
  1055. .insertnewitem5
  1056. x8teq    r6,r8                  ;don't copy terminator
  1057. ldrneb r2,[r6],#1
  1058. strneb r2,[r1],#1
  1059. bne    insertnewitem5
  1060. .insertnewitem6
  1061. ~Lsub    r1,r8,r10              ;for pre-RO3.5 - calculate menu item width
  1062. mov    r1,r1,lsl#4
  1063. add    r1,r1,#12
  1064. ldmia  r0,{r2-r3}
  1065. cmp    r2,r1
  1066. movlt  r2,r1
  1067. 7add    r3,r3,#1               ;increase nr of items
  1068. stmia  r0,{r2-r3}
  1069. ldmfd  sp !,{r2-r6,pc}^
  1070. -;________________________________________
  1071. .indirmatch
  1072. K;on entry r10=ptr to string (need not be terminated), r4=start of scan,
  1073. @;         r5=end of scan=addr indirused, r6=length of string
  1074. O;on exit  r5=addr of match with highest address or C set if no match found,
  1075. ;         r4 corrupt
  1076. P;NB this will only find ALL matches for search strings >=7 chars in length -
  1077. >;but then it's unlikely for *commands to be shorter anyway
  1078. bic    lr,lr,#1<<29
  1079. !stmfd  sp !,{r0-r3,r6-r12,lr}
  1080. and    r6,r10,#3
  1081. mov    r6,r6,lsl#3
  1082. bic    r7,r10,#3
  1083. ldmia  r7,{r0,r3,r8}
  1084. bic    r5,r5,#3
  1085. rsb    r7,r6,#32
  1086. mov    r0,r0,lsr r6
  1087. orr    r0,r0,r3,lsl r7
  1088. mov    r3,r3,lsr r6
  1089. orr    r3,r3,r8,lsl r7
  1090. mov    r1,r0,lsr#8
  1091. orr    r1,r1,r3,lsl#24
  1092. mov    r2,r0,lsr#16
  1093. orr    r2,r2,r3,lsl#16
  1094. mov    r3,r3,lsl#8
  1095. orr    r3,r3,r0,lsr#24
  1096. d("indirmatch^^string at ^10^, (^0^/^1^/^2^/^3^) $10^")
  1097. d("indirmatch^^string at ^10^: $10^")
  1098. .indirmatch1
  1099. ldmdb  r5!,{r6-r12}
  1100. Hteq   r12,r0:teqne r12,r1:teqne r12,r2:teqne r12,r3:bleq indirmatch3
  1101. Hteq   r11,r0:teqne r11,r1:teqne r11,r2:teqne r11,r3:bleq indirmatch3
  1102. Hteq   r10,r0:teqne r10,r1:teqne r10,r2:teqne r10,r3:bleq indirmatch3
  1103. Hteq    r9,r0:teqne  r9,r1:teqne  r9,r2:teqne  r9,r3:bleq indirmatch3
  1104. Hteq    r8,r0:teqne  r8,r1:teqne  r8,r2:teqne  r8,r3:bleq indirmatch3
  1105. Hteq    r7,r0:teqne  r7,r1:teqne  r7,r2:teqne  r7,r3:bleq indirmatch3
  1106. Hteq    r6,r0:teqne  r6,r1:teqne  r6,r2:teqne  r6,r3:bleq indirmatch3
  1107. .indirmatch2
  1108. cmp    r5,r4
  1109. bhi    indirmatch1
  1110. !ldmfd  sp !,{r0-r3,r6-r12,lr}
  1111. orrs   pc,lr,#1<<29
  1112. ;____________
  1113. .indirmatch3
  1114. stmfd  sp !,{r7-r12,lr}
  1115. bic    lr,lr,#&FC000003
  1116. adr    r12,indirmatch2
  1117. ?sub    r12,r12,lr             ;r12 is 0/20/40/60/80/100/120
  1118. ?mov    r12,r12,lsr#4          ;r12 is 0/ 1/ 2/ 3/ 5/  6/  7
  1119. Lcmp    r12,#5                 ;er - not quite the way we did division in
  1120. Lsubge  r12,r12,#1             ;school, but it works (only in this case!)
  1121. add    r14,r5,r12,lsl#2
  1122. ldr    r12,[r14]
  1123. teq    r12,r0
  1124. beq    indirmatch7
  1125. .indirmatch4
  1126. teq    r12,r1
  1127. beq    indirmatch8
  1128. .indirmatch5
  1129. teq    r12,r2
  1130. beq    indirmatch9
  1131. .indirmatch6
  1132. teq    r12,r3
  1133. ldmnefdsp !,{r7-r12,pc}
  1134. ;______
  1135. .indirmatch10
  1136. sub    r11,r14,#3
  1137. @ldr    r9,[sp,#7*4+4*4]       ;get r6 on entry to indirmatch
  1138. Aldr    r10,[sp,#7*4+8*4]      ;get r10 on entry to indirmatch
  1139. .indirmatch10a
  1140. ldrb   r7,[r10],#1
  1141. ldrb   r8,[r11],#1
  1142. teq    r7,r8
  1143. +ldmnefdsp !,{r7-r12,pc}       ;no match
  1144. subs   r9,r9,#1
  1145. bne    indirmatch10a
  1146. Pldrb   r8,[r11]               ;all chars the same, now check if found string
  1147. 0cmp    r8,#32                 ;is terminated
  1148. ldmgefdsp !,{r7-r12,pc} 
  1149. 8ldr    r9,[sp,#7*4+4*4]       ;get r6 on entry again
  1150. sub    r8,r11,r9
  1151. Bcmp    r8,r4                  ;still above low end of scanned?
  1152. ldmlofdsp !,{r7-r12,pc} 
  1153. /add    sp,sp,#7*4             ;match found!
  1154. mov    r5,r8
  1155. "ldmfd  sp !,{r0-r3,r6-r12,pc}^
  1156. ;____________
  1157. .indirmatch7
  1158. mov    r11,r14
  1159. @ldr    r9,[sp,#7*4+4*4]       ;get r6 on entry to indirmatch
  1160. Aldr    r10,[sp,#7*4+8*4]      ;get r10 on entry to indirmatch
  1161. .indirmatch7a
  1162. ldrb   r7,[r10],#1
  1163. ldrb   r8,[r11],#1
  1164. teq    r7,r8
  1165. +bne    indirmatch4            ;no match
  1166. subs   r9,r9,#1
  1167. bne    indirmatch7a
  1168. Pldrb   r8,[r11]               ;all chars the same, now check if found string
  1169. 0cmp    r8,#32                 ;is terminated
  1170. bge    indirmatch4
  1171. 8ldr    r9,[sp,#7*4+4*4]       ;get r6 on entry again
  1172. sub    r8,r11,r9
  1173. Bcmp    r8,r4                  ;still above low end of scanned?
  1174. blo    indirmatch4
  1175. /add    sp,sp,#7*4             ;match found!
  1176. mov    r5,r8
  1177. "ldmfd  sp !,{r0-r3,r6-r12,pc}^
  1178. ;____________
  1179. .indirmatch8
  1180. sub    r11,r14,#1
  1181. @ldr    r9,[sp,#7*4+4*4]       ;get r6 on entry to indirmatch
  1182. Aldr    r10,[sp,#7*4+8*4]      ;get r10 on entry to indirmatch
  1183. .indirmatch8a
  1184. ldrb   r7,[r10],#1
  1185. ldrb   r8,[r11],#1
  1186. teq    r7,r8
  1187. +bne    indirmatch5            ;no match
  1188. subs   r9,r9,#1
  1189. bne    indirmatch8a
  1190. Pldrb   r8,[r11]               ;all chars the same, now check if found string
  1191. 0cmp    r8,#32                 ;is terminated
  1192. bge    indirmatch5
  1193. 8ldr    r9,[sp,#7*4+4*4]       ;get r6 on entry again
  1194. sub    r8,r11,r9
  1195. Bcmp    r8,r4                  ;still above low end of scanned?
  1196. blo    indirmatch5
  1197. /add    sp,sp,#7*4             ;match found!
  1198. mov    r5,r8
  1199. "ldmfd  sp !,{r0-r3,r6-r12,pc}^
  1200. ;____________
  1201. .indirmatch9
  1202. sub    r11,r14,#2
  1203. @ldr    r9,[sp,#7*4+4*4]       ;get r6 on entry to indirmatch
  1204. Aldr    r10,[sp,#7*4+8*4]      ;get r10 on entry to indirmatch
  1205. .indirmatch9a
  1206. ldrb   r7,[r10],#1
  1207. ldrb   r8,[r11],#1
  1208. teq    r7,r8
  1209. +bne    indirmatch6            ;no match
  1210. subs   r9,r9,#1
  1211. bne    indirmatch9a
  1212. Pldrb   r8,[r11]               ;all chars the same, now check if found string
  1213. 0cmp    r8,#32                 ;is terminated
  1214. bge    indirmatch6
  1215. !8ldr    r9,[sp,#7*4+4*4]       ;get r6 on entry again
  1216. sub    r8,r11,r9
  1217. #Bcmp    r8,r4                  ;still above low end of scanned?
  1218. blo    indirmatch6
  1219. %/add    sp,sp,#7*4             ;match found!
  1220. mov    r5,r8
  1221. '"ldmfd  sp !,{r0-r3,r6-r12,pc}^
  1222. (-;________________________________________
  1223. .syntaxerror
  1224. +!mov    r3,#Err_UnknownCommand
  1225. ;r3=error number
  1226. .?;returns messages to make debugging of the Menu file easier
  1227. .report
  1228. mov    r0,#240
  1229. mov    r1,#0
  1230. mov    r2,#&ff
  1231. 34swi    "OS_Byte"              ;r1=country number
  1232. adr    r4,errormessages
  1233. teq    r1,#7
  1234. adreq  r4,errormessages7
  1235. add    r1,r12,#string
  1236. 9Dorr    r5,r3,#1<<30           ;set bit 30 - recommended by Acorn
  1237. stmia  r1!,{r5}
  1238. ; ldr    r0,[r12,#currentline]
  1239. .report1
  1240. ldrb   r5,[r4],#1
  1241. teq    r5,#
  1242. moveq  r2,#256
  1243. A6swieq  "XOS_BinaryToDecimal"  ;convert line number
  1244. addeq  r1,r1,r2
  1245. beq    report1
  1246. teq    r5,#0
  1247. strneb r5,[r1],#1
  1248. bne    report1
  1249. HM.report2                      ;count down found 0s to find correct string
  1250. ldrb   r5,[r4],#1
  1251. teq    r5,#0
  1252. subeqs r3,r3,#1
  1253. bne    report2
  1254. M..report3                      ;copy string
  1255. ldrb   r5,[r4],#1
  1256. strb   r5,[r1],#1
  1257. teq    r5,#0
  1258. bne    report3
  1259. add    r0,r12,#string
  1260. ;______
  1261. .error
  1262. mov    r1,r0
  1263. bl     closedown
  1264. mov    r0,r1
  1265. ldmfd  sp !,{lr}
  1266. orrs   pc,lr,#1<<28
  1267. [-;________________________________________
  1268. .closedown
  1269. bic    lr,lr,#1<<28
  1270. stmfd  sp !,{r0-r2,r11,lr}
  1271. mov    r11,#0
  1272. ldr    r1,[r12,#sourceh]
  1273. cmn    r1,#1
  1274. beq    closedown1
  1275. mov    r0,#0
  1276. swi    "XOS_Find"
  1277. movvs  r11,r0
  1278. .closedown1
  1279. ldr    r1,[r12,#desth]
  1280. cmn    r1,#1
  1281. beq    closedown2
  1282. mov    r0,#0
  1283. swi    "XOS_Find"
  1284. movvs  r11,r0
  1285. .closedown2
  1286. mov    r0,#7
  1287. ldr    r2,[r12,#menu]
  1288. teq    r2,#0
  1289. beq    closedown3
  1290. swi    "XOS_Module"
  1291. movvs  r11,r0
  1292. .closedown3
  1293. ldr    r2,[r12,#indir]
  1294. teq    r2,#0
  1295. beq    closedown4
  1296. swi    "XOS_Module"
  1297. movvs  r11,r0
  1298. .closedown4
  1299. teq    r11,#0
  1300. ldmeqfdsp !,{r0-r2,r11,pc}^
  1301. stmfd  sp,{r11}
  1302. ldmfd  sp !,{r0-r2,r11,lr}
  1303. orrs   pc,lr,#1<<28
  1304. -;________________________________________
  1305. .errormessages
  1306. 0dcb"File 
  1307. !MyMenu.Menu.Menu
  1308. , line %: ":dcb0
  1309. dcb"Syntax error":dcb0
  1310. ?dcb"There must only be one character after 
  1311. Special:
  1312. ":dcb0
  1313. <dcb"The special character has already been defined":dcb0
  1314. 8dcb"The special character has not been defined":dcb0
  1315. "dcb"The line is too long":dcb0
  1316. 5dcb"Unknown modifier at the end of the line":dcb0
  1317. 7dcb"Wrong 
  1318.  modifier at the end of the line":dcb0
  1319. 7dcb"Wrong 
  1320.  modifier at the end of the line":dcb0
  1321. 7dcb"Wrong 
  1322.  modifier at the end of the line":dcb0
  1323. 7dcb"Wrong 
  1324.  modifier at the end of the line":dcb0
  1325. Kdcb"Only one item in the menu structure can have the 
  1326.  modifier":dcb0
  1327. Ldcb"A menu entry needs to be followed by at least one command line":dcb0
  1328. Idcb"There is a menu with no entries in it 
  1329.  this is not allowed":dcb0
  1330. Cdcb"No hotkeys have been defined for a menu or menu entry":dcb0
  1331. Pdcb"This command must appear before any menu or menu entry definitions":dcb0
  1332. Odcb"The hotkey specified in the 
  1333.  modifier has already been defined":dcb0
  1334.     align
  1335. .errormessages7
  1336. 2dcb"Datei 
  1337. !MyMenu.Menu.Menu
  1338. , Zeile %: ":dcb0
  1339. dcb"Syntax-Fehler":dcb0
  1340. 9dcb"Nach 
  1341. Special:
  1342.  darf nur ein Zeichen stehen":dcb0
  1343. 9dcb"Das Spezial-Zeichen wurde bereits definiert":dcb0
  1344. <dcb"Das Spezial-Zeichen wurde noch nicht definiert":dcb0
  1345. #dcb"Die Zeile ist zu lang":dcb0
  1346. 2dcb"Unbekannter Zusatz am Ende der Zeile":dcb0
  1347. 3dcb"Falscher 
  1348. -Zusatz am Ende der Zeile":dcb0
  1349. 3dcb"Falscher 
  1350. -Zusatz am Ende der Zeile":dcb0
  1351. 3dcb"Falscher 
  1352. -Zusatz am Ende der Zeile":dcb0
  1353. 3dcb"Falscher 
  1354. -Zusatz am Ende der Zeile":dcb0
  1355. [dcb"Nur ein Men
  1356.  oder Men
  1357. eintrag des gesamten Men
  1358. s darf den 
  1359. -Zusatz besitzen":dcb0
  1360. Kdcb"Auf einen Men
  1361. eintrag mu
  1362.  mindestens eine Befehlszeile folgen":dcb0
  1363. Ddcb"Es gibt ein Men
  1364.  ohne Eintr
  1365.  das ist nicht erlaubt":dcb0
  1366. Odcb"Es wurden keinerlei Hotkeys f
  1367. r Men
  1368. s oder Men
  1369. eintr
  1370. ge definiert":dcb0
  1371. `dcb"Dieser Befehl mu
  1372.  in der Datei vor Definitionen f
  1373. r Men
  1374. s oder Men
  1375. eintr
  1376. ge stehen":dcb0
  1377. Rdcb"Die im 
  1378. -Zusatz genannte Tastenkombination wurde bereits definiert":dcb0
  1379. -;________________________________________
  1380. debugging%
  1381.   [optp
  1382.   align
  1383. debug(p,washerefile$,20):]
  1384. :[optp
  1385. ]:end%=O%:[optp
  1386. rmablock(p)
  1387. -;________________________________________
  1388. ]O%+=128:[optp:]:O%-=128
  1389. 2)=0 A$=
  1390. i%=code% 
  1391. 128:$i%=A$:
  1392. "Size: ";end%-code%"/&"~end%-code%" bytes (";
  1393. ((end%-code%)/102.4+.5)/10" kBytes)."'"Time: ";
  1394. /100" seconds."
  1395. "Save "+save$+" "+
  1396. ~code%+" "+
  1397. ~end%:
  1398. "SetType "+save$+" "+type$
  1399.  REPEAT:A%=INKEY(0):MOUSEB%,B%,C%:UNTIL A%>-1ORC%>0
  1400.  SYS"OS_Module",11,code%,O%-code%
  1401. rmablock(p)
  1402. P%:Otemp%=O%:[optp
  1403. -;________________________________________
  1404. ;offsets in RMA block
  1405. .sourceh       dcd0
  1406. .sourceeof     dcd0
  1407. .desth         dcd0
  1408. .currentline   dcd0
  1409. *.stringstart   dcd0           ;address
  1410. B.stringend     dcd0           ;address of terminator of string
  1411. G.entrymenu     dcd0           ;nr of menu entries will be placed in
  1412. Q.leafmenuitem  dcd0          ;(address of item 4 curr. leaf submenu level)+16
  1413. @.nrofmenus     dcd0           ;excluding invisible main menu
  1414. L.hotkey        dcd0           ;(8 bytes each) stored downwards from +896
  1415. O.mouse         dcd0           ;menu nr/item nr if MENU clicked on left side
  1416. L.osclilen      dcd0           ;size of the largest non-buffered *command
  1417. L.menu          dcd0 ;\        ;address of RMA block containing menu data
  1418. .menusize      dcd0 ; \
  1419. <.menuused      dcd0 ;  \      ;nr of bytes actually used
  1420. K.indir         dcd0 ;\        ;address of RMA block containing data for
  1421. E.indirsize     dcd0 ; \       ;  indirected icons & star commands
  1422. <.indirused     dcd0 ;  \      ;nr of bytes actually used
  1423. .special       dcb0
  1424. .bufferallinit dcb0
  1425. P.bufferall     dcb0           ;non-zero to buffer *comms of all menu entries
  1426. .ondemand      dcb0
  1427.     align
  1428. .var_end
  1429. .string
  1430. .rmablocksize%
  1431. -;________________________________________
  1432. rmablocksize%>1024-128 
  1433. O%=Otemp%:=0
  1434. d(a$)
  1435. debugging%
  1436.   [optp
  1437.   bl     IWasHere
  1438.   dcb a$:dcb0:align:]
  1439.